home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2009 February / PCWFEB09.iso / Software / Linux / Kubuntu 8.10 / kubuntu-8.10-desktop-i386.iso / casper / filesystem.squashfs / lib / udev / path_id < prev    next >
Text File  |  2008-10-24  |  12KB  |  566 lines

  1. #!/bin/sh
  2.  
  3. # provide the shortest possible unique hardware path to a device
  4. # for the Linux Persistent Device Naming scheme
  5. #
  6. # Copyright (C) 2005-2006 SUSE Linux Products GmbH
  7. # Author:
  8. #    Hannes Reinecke <hare@suse.de>
  9. #
  10. #    This program is free software; you can redistribute it and/or modify it
  11. #    under the terms of the GNU General Public License as published by the
  12. #    Free Software Foundation version 2 of the License.
  13.  
  14. SYSFS=/sys
  15. RESULT=1
  16. TYPE=
  17. OPWD="`pwd`"
  18. full_sysfs_path=
  19. full_sysfs_device_path=
  20.  
  21. if [ -z "$DEVPATH" -a -z "$1" ] ; then
  22.     exit 1
  23. fi
  24.  
  25. if [ -z "$DEVPATH" ] ; then
  26.     case "$1" in
  27.         $SYSFS/*)
  28.             DEVPATH="${1#$SYSFS}"
  29.             ;;
  30.         *)
  31.             DEVPATH=$1
  32.             ;;
  33.     esac
  34. fi
  35.  
  36. if [ ! -e $SYSFS$DEVPATH/dev ] ; then
  37.     exit 1
  38. fi
  39.  
  40. case "$DEVPATH" in
  41.     /devices/*)
  42.         cd "$SYSFS$DEVPATH/subsystem";
  43.         TYPE="`pwd -P`"
  44.         cd "$OPWD"
  45.         TYPE="${TYPE##*/}"
  46.         ;;
  47.     /class/*)
  48.         TYPE="${DEVPATH#/class/}"
  49.         TYPE="${TYPE%%/*}"
  50.         ;;
  51.     /block/*)
  52.         TYPE=block
  53.         ;;
  54.     *)
  55.         exit 1
  56.         ;;
  57. esac
  58.  
  59. get_port_offset () {
  60.     local type offset port
  61.     type=$1
  62.     offset=$2
  63.     for i in $type[0-9]* ; do
  64.         : i $i
  65.         port="${i#$type}"
  66.         if [ "$port" -lt "$offset" ] ; then offset=$port ; fi
  67.     done
  68.     echo $offset
  69. }
  70.  
  71. handle_pci () {
  72.     local DEV=$1
  73.     cd -P $1
  74.     DEV=${PWD}
  75.     pci_id=${DEV##*/}
  76.     host_dev_path=$DEV
  77.  
  78.     # cciss devices don't have a separate sysfs node
  79.     for blk_link in block*; do
  80.         if [ -L "$blk_link" ]; then
  81.         case "$blk_link" in
  82.             *cciss*)
  83.             d=cciss-${blk_link#*cciss\!}
  84.             ;;
  85.         esac
  86.         fi
  87.     done
  88.     while [ ! -z "$host_dev_path" ] ; do
  89.         case "$host_dev_path" in
  90.             */pci[0-9]*)
  91.                 host_dev_path=${host_dev_path%/*}
  92.                 ;;
  93.             *)
  94.                 break
  95.                 ;;
  96.         esac
  97.     done
  98.     d="pci-$pci_id-$d"
  99.     D="$host_dev_path"
  100.     RESULT=0
  101. }
  102.  
  103. handle_platform () {
  104.     local DEV=$1
  105.     cd -P $1
  106.     DEV=${PWD}
  107.     platform_id=${DEV##*/}
  108.     host_dev_path=$DEV
  109.     while [ ! -z "$host_dev_path" ] ; do
  110.         case "$host_dev_path" in
  111.             */platform*)
  112.                 host_dev_path=${host_dev_path%/*}
  113.                 ;;
  114.             *)
  115.                 break
  116.                 ;;
  117.         esac
  118.     done
  119.     if [ "$d" ]; then
  120.         d="platform-$platform_id-$d"
  121.     else
  122.         d="platform-$platform_id"
  123.     fi
  124.     D="$host_dev_path"
  125.     RESULT=0
  126. }
  127.  
  128. handle_serio () {
  129.     local DEV=$1
  130.     cd -P $1
  131.     DEV=${PWD}
  132.     serio_id=${DEV##*/serio}
  133.     host_dev_path=$DEV
  134.     while [ ! -z "$host_dev_path" ] ; do
  135.         case "$host_dev_path" in
  136.             */serio*)
  137.                 host_dev_path=${host_dev_path%/*}
  138.                 ;;
  139.             *)
  140.                 break
  141.                 ;;
  142.         esac
  143.     done
  144.     if [ "$d" ]; then
  145.         d="serio-$serio_id-$d"
  146.     else
  147.         d="serio-$serio_id"
  148.     fi
  149.     D="$host_dev_path"
  150.     RESULT=0
  151. }
  152.  
  153. handle_ide () {
  154.     : handle_ide $*
  155.     local DEV=$1
  156.     local port idedev idecontroller
  157.     # IDE
  158.     : DEV $DEV
  159.     port=${DEV##*/}
  160.     idedev=${DEV%/*}
  161.     idecontroller=${idedev%/*}
  162.     # port info if the controller has more than one interface
  163.     port="${port#ide}"
  164.     : port $port d $d
  165.     : idedev $idedev kernel_port $port
  166.     case "${port#*.}" in
  167.         0)
  168.             channel=0
  169.             ;;
  170.         1)
  171.             channel=1
  172.             ;;
  173.         *)
  174.             echo "Error: $idedev is neither master or slave" >&2
  175.             ;;
  176.     esac
  177.     cd $idecontroller
  178.     offset="`get_port_offset ide ${port%.*}`"
  179.     cd "$OPWD"
  180.     :  port offset $offset
  181.     port=$((${port%.*} - $offset))
  182.     if [ "$d" ] ; then
  183.         d="ide-${port}:$channel-$d"
  184.     else
  185.         d="ide-${port}:$channel"
  186.     fi
  187.     D=$idecontroller
  188.     RESULT=0
  189. }
  190.  
  191. handle_scsi () {
  192.     : handle_scsi $*
  193.     local DEV=$1
  194.     local cil controller_port controller_dev
  195.     # SCSI device
  196.     cil="${DEV##*/}"
  197.     cil="${cil#*:}"
  198.     target_dev=${DEV%/*}
  199.     target_id=${target_dev##*/target}
  200.     cd "$target_dev"
  201.     target_num=0
  202.     for tid in ${target_id}* ; do
  203.         target_num=$(( $target_num + 1 ))
  204.     done
  205.     controller_port=${target_dev%/*}
  206.     controller_dev="${controller_port%/*}"
  207.     : controller_dev $controller_dev
  208.     : controller_port $controller_port
  209.     # a host controller may have more than one interface/port
  210.     controller_port="${controller_port##*/host}"
  211.     #
  212.     cd "$controller_dev"
  213.     controller_offset=$(get_port_offset host $controller_port)
  214.     cd "$OPWD"
  215.     controller_port=$(( $controller_port - $controller_offset))
  216.     scsi_id="scsi-${controller_port}:${cil}"
  217.     if [ "$d" ] ; then
  218.         d="${scsi_id}-$d"
  219.     else
  220.         d="$scsi_id"
  221.     fi
  222.     D="$controller_dev"
  223.     RESULT=0
  224. }
  225.  
  226. handle_firewire () {
  227.     : handle_firewire $*
  228.     local DEV=$1
  229.     if [ -f "$D/ieee1394_id" ] ; then
  230.         read ieee1394_id < $D/ieee1394_id
  231.     fi
  232.     if [ -z "$ieee1394_id" ] ; then
  233.         : no IEEE1394 ID
  234.         RESULT=1
  235.         return
  236.     fi
  237.     fw_host_dev=${DEV%/fw-host*}
  238.     # IEEE1394 devices are always endpoints
  239.     d="ieee1394-0x$ieee1394_id"
  240.     D="$fw_host_dev"
  241.     RESULT=0
  242. }
  243.  
  244. handle_fc () {
  245.     : handle_fc $*
  246.     local DEV=$1
  247.     local cil controller_port controller_dev
  248.     # SCSI-FC device
  249.     fc_tgt_hcil="${DEV##*/}"
  250.     fc_tgt_lun="${fc_tgt_hcil##*:}"
  251.     fc_tgt_path="${DEV%/*}"
  252.     fc_tgt_num="${fc_tgt_path##*/}"
  253.     fc_tgt_dev="${fc_tgt_path}/fc_transport:${fc_tgt_num}"
  254.     if [ -e "$fc_tgt_dev/port_name" ]; then
  255.         read wwpn < $fc_tgt_dev/port_name
  256.     fi
  257.     if [ -z "$wwpn" ] ; then
  258.         : no WWPN
  259.         D=
  260.         RESULT=1
  261.         return
  262.     fi
  263.     # Linux currently knows about 32bit luns
  264.     tmp_lun3=$(printf "%04x" $(($fc_tgt_lun & 0xFFFF)))
  265.     tmp_lun2=$(printf "%04x" $(( ($fc_tgt_lun >> 16) & 0xFFFF)))
  266.     tmp_lun1="0000"
  267.     tmp_lun0="0000"
  268.     if (($fc_tgt_lun == 0)) ; then
  269.         lun="0x0000000000000000"
  270.     else
  271.         lun="0x${tmp_lun3}${tmp_lun2}${tmp_lun1}${tmp_lun0}"
  272.     fi
  273.     controller_dev="${fc_tgt_path%/host[0-9]*}"
  274.     # FC devices are always endpoints
  275.     d="fc-${wwpn}:${lun}"
  276.     D="$controller_dev"
  277.     RESULT=0
  278. }
  279.  
  280. handle_sas () {
  281.     : handle_sas $*
  282.     local DEV=$1
  283.     local cil adapter controller_dev
  284.     # SAS device
  285.     sas_host_path="${DEV%%/port*}"
  286.     sas_phy_path="${DEV#*/host*/}"
  287.     sas_phy_path="${sas_phy_path%%/target*}"
  288.     sas_phy_id="${sas_phy_path%%/*}"
  289.     sas_phy_id="${sas_phy_id##*port-}"
  290.     sas_port_id="${sas_phy_path%%/end_device*}"
  291.     sas_port_id="${sas_port_id##*port-}"
  292.     sas_end_id="${sas_phy_path##*end_device-}"
  293.     sas_phy_dev="/sys/class/sas_phy/phy-${sas_phy_id}"
  294.     if [ -e "$sas_phy_dev/sas_address" ]; then
  295.         read phy_address < $sas_phy_dev/sas_address
  296.         read phy_id < $sas_phy_dev/phy_identifier
  297.     fi
  298.     if [ -z "$phy_address" ] ; then
  299.         : no initiator address
  300.         D=
  301.         RESULT=1
  302.         return
  303.     fi
  304.     sas_port_dev="/sys/class/sas_port/port-${sas_port_id}"
  305.     if [ -e "$sas_port_dev/num_phys" ] ; then
  306.         read phy_port < $sas_port_dev/num_phys
  307.     fi
  308.     if [ -z "$phy_port" ] ; then
  309.         : no initiator address
  310.         D=
  311.         RESULT=1
  312.         return
  313.     fi
  314.     sas_phy_address="$phy_address:$phy_port:$phy_id"
  315.     sas_end_dev="/sys/class/sas_device/end_device-${sas_end_id}"
  316.     if [ -e "$sas_end_dev/sas_address" ]; then
  317.         read end_address < $sas_end_dev/sas_address
  318.         read end_id < $sas_end_dev/phy_identifier
  319.     fi
  320.     if [ -z "$end_address" ] ; then
  321.         : no initiator address
  322.         D=
  323.         RESULT=1
  324.         return
  325.     fi
  326.     sas_end_address="$end_address:$end_id"
  327.     controller_dev="${sas_host_path%/host[0-9]*}"
  328.     # SAS devices are always endpoints
  329.     d="sas-${sas_phy_address}-${sas_end_address}"
  330.     D="$controller_dev"
  331.     RESULT=0
  332. }
  333.  
  334. handle_iscsi() {
  335.     local DEV=$1
  336.     local iscsi_session_dir
  337.     local iscsi_session iscsi_session_path
  338.     local iscsi_connection iscsi_connection_path
  339.     local iscsi_scsi_lun
  340.     # iSCSI device
  341.     iscsi_session_dir="${DEV%%/target*}"
  342.     iscsi_session="${iscsi_session_dir##*/}"
  343.     iscsi_session_path=/sys/class/iscsi_session/${iscsi_session}
  344.     if [ ! -d "$iscsi_session_path" ] ; then
  345.         : no iSCSI session path
  346.         RESULT=1
  347.         return
  348.     fi
  349.     # Currently we're not doing MC/S
  350.     for conn in ${iscsi_session_dir}/connection* ; do
  351.         iscsi_conn_num=${conn##*:}
  352.         if [ "$iscsi_conn_num" = '0' ] ; then
  353.         iscsi_connection=$(basename $conn)
  354.         fi
  355.     done
  356.     if [ -z "$iscsi_connection" ] ; then
  357.         : no iSCSI connection found
  358.         RESULT=1
  359.         return
  360.     fi
  361.     iscsi_connection_path=/sys/class/iscsi_connection/${iscsi_connection}
  362.     if [ ! -d "$iscsi_connection_path" ] ; then
  363.         : no iSCSI connection path
  364.         RESULT=1
  365.         return
  366.     fi
  367.     if [ -e "${iscsi_session_path}/targetname" ]; then
  368.         read iscsi_tgtname < ${iscsi_session_path}/targetname
  369.     fi
  370.     if [ -z "$iscsi_tgtname" ] ; then
  371.         : No iSCSI Targetname
  372.         RESULT=1
  373.         return
  374.     fi
  375.     if [ -e "${iscsi_connection_path}/persistent_address" ] ; then
  376.         read iscsi_address < ${iscsi_connection_path}/persistent_address
  377.     fi
  378.     if [ -z "$iscsi_address" ] ; then
  379.         : No iSCSI Target address
  380.         RESULT=1
  381.         return
  382.     fi
  383.     if [ -e "${iscsi_connection_path}/persistent_port" ] ; then
  384.         read iscsi_port < ${iscsi_connection_path}/persistent_port
  385.     fi
  386.     iscsi_scsi_lun="${DEV##*:}"
  387.     d="ip-${iscsi_address}:${iscsi_port}-iscsi-${iscsi_tgtname}-lun-${iscsi_scsi_lun}"
  388.     RESULT=0
  389. }
  390.  
  391. handle_usb () {
  392. : handle_usb $*
  393.     local DEV=$1
  394.     cd -P $1
  395.     DEV=${PWD}
  396.     port_id=${DEV##*/}
  397.     port_num=${port_id#*-}
  398.     host_dev_path=$DEV
  399.     while [ ! -z "$host_dev_path" ] ; do
  400.         case "$host_dev_path" in
  401.             */usb*)
  402.                 usb_host_path=$host_dev_path
  403.                 host_dev_path="${host_dev_path%/*}"
  404.                 ;;
  405.             *)
  406.                 break
  407.                 ;;
  408.         esac
  409.     done
  410.     : host_dev_path $host_dev_path
  411.     usb_host_num=${usb_host_path##*/usb}
  412.  
  413.     cd "$host_dev_path"
  414.     usb_host_offset=$(get_port_offset usb $usb_host_num)
  415.     usb_host_port=$(($usb_host_num - $usb_host_offset))
  416.     cd "$OPWD"
  417.     if [ "$d" ] ; then
  418.         d="usb-$usb_host_port:$port_num-${d}"
  419.     else
  420.         d="usb-$usb_host_port:$port_num"
  421.     fi
  422.     D="$host_dev_path"
  423.     RESULT=0
  424. }
  425.  
  426. handle_device () {
  427.     full_sysfs_path="$SYSFS$DEVPATH"
  428.     case "$DEVPATH" in
  429.         /devices/*)
  430.             full_sysfs_path="${full_sysfs_path%/*}"
  431.             # skip parent device of the same subsystem
  432.             if [ -L $full_sysfs_path/subsystem ]; then
  433.                 cd "$full_sysfs_path/subsystem";
  434.                 subsys="`pwd -P`"
  435.                 cd "$OPWD"
  436.                 subsys="${subsys##*/}"
  437.                 if [ "$subsys" = "$TYPE" ]; then
  438.                     : skip same subsystem parent
  439.                     full_sysfs_path="${full_sysfs_path%/*}"
  440.                 fi
  441.             fi
  442.             # skip subsystem directory
  443.             subsys="${full_sysfs_path##*/}"
  444.             if [ "$subsys" = "$TYPE" ]; then
  445.                 : skip subsystem directory
  446.                 full_sysfs_path="${full_sysfs_path%/*}"
  447.             fi
  448.             cd $full_sysfs_path
  449.             ;;
  450.         *)
  451.             # old sysfs layout
  452.             if [ ! -L $full_sysfs_path/device ]; then
  453.                 full_sysfs_path="${full_sysfs_path%/*}"
  454.                 : full_sysfs_path "$full_sysfs_path"
  455.                 if [ ! -L $full_sysfs_path/device -o ! -f $full_sysfs_path/dev ]; then
  456.                     return
  457.                 fi
  458.             fi
  459.             if [ -L $full_sysfs_path/device/device ]; then
  460.                 cd $full_sysfs_path/device/device
  461.             else
  462.                 cd $full_sysfs_path/device
  463.             fi
  464.             ;;
  465.     esac
  466.     full_sysfs_device_path="`pwd -P`"
  467.     cd "$OPWD"
  468.  
  469.     D=$full_sysfs_device_path
  470.     while [ ! -z "$D" ] ; do
  471.         case "$D" in
  472.             */ide[0-9]/[0-9].[0-9]*|*/ide[0-9][0-9]/[0-9][0-9].[0-9]*)
  473.                 handle_ide "$D"
  474.                 ;;
  475.             */css0/*)
  476.                 if [ -r $full_sysfs_device_path/wwpn ]; then
  477.                     read wwpn < $full_sysfs_device_path/wwpn
  478.                 fi
  479.                 if [ -r $full_sysfs_device_path/fcp_lun ]; then
  480.                     read lun < $full_sysfs_device_path/fcp_lun
  481.                 fi
  482.                 if [ -r $full_sysfs_device_path/hba_id ]; then
  483.                     read bus_id < $full_sysfs_device_path/hba_id
  484.                 fi
  485.                 if [ "$bus_id" -a "$wwpn" -a "$lun" ]; then
  486.                     # S/390 zfcp adapter
  487.                     d="ccw-$bus_id-zfcp-$wwpn:$lun"
  488.                     RESULT=0
  489.                 else
  490.                     # DASD devices
  491.                     bus="ccw"
  492.                     adapter=${D##*/}
  493.                     d="$bus-$adapter"
  494.                     RESULT=0
  495.                 fi
  496.                 D=
  497.                 ;;
  498.             */rport-[0-9]*:[0-9]*-[0-9]*/*)
  499.                 handle_fc "$D"
  500.                 ;;
  501.             */end_device-[0-9]*:[0-9]*:[0-9]*/*)
  502.                 handle_sas "$D"
  503.                 ;;
  504.             */fw-host[0-9]*/*)
  505.                 handle_firewire "$D"
  506.                 ;;
  507.             */session[0-9]*/*)
  508.                 handle_iscsi "$D"
  509.                 D=
  510.                 ;;
  511.             */host[0-9]*/[0-9]*:[0-9]*:[0-9]*:[0-9]*)
  512.                 handle_scsi "$D"
  513.                 ;;
  514.             */usb[0-9]*/[0-9]*/*)
  515.                 handle_usb "$D"
  516.                 ;;
  517.             */pci[0-9]*:[0-9]*)
  518.                 handle_pci "$D"
  519.                 ;;
  520.             */serio[0-9]*)
  521.                 handle_serio "$D"
  522.                 ;;
  523.             */platform/*)
  524.                 handle_platform "$D"
  525.                 ;;
  526.             */devices)
  527.                 D=
  528.                 ;;
  529.             *)
  530.                 : not handled
  531.                 RESULT=1
  532.                 return
  533.                 ;;
  534.         esac
  535.     done
  536.     if [ "$TYPE" = "scsi_tape" ] ; then
  537.         devname=${full_sysfs_path##*/}
  538.         rewind="${devname%%st*}"
  539.         mode="${devname##*st}"
  540.         case "$mode" in
  541.             *l)
  542.                 mode="l"
  543.                 ;;
  544.             *m)
  545.                 mode="m"
  546.                 ;;
  547.             *a)
  548.                 mode="a"
  549.                 ;;
  550.             *)
  551.                 mode=""
  552.                 ;;
  553.         esac
  554.         if [ "$d" ]; then
  555.             d="$d-${rewind}st${mode}"
  556.         fi
  557.     fi
  558. }
  559.  
  560. handle_device
  561. if [ -z "$d" ]; then
  562.     exit 1
  563. fi
  564. echo "ID_PATH=$d"
  565. exit 0
  566.